#ifndef DISK_SCHEDULER_HPP
#define DISK_SCHEDULER_HPP

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <cmath>
#include <iomanip>

class DiskScheduler {
public:
    // 构造函数：初始化调度器
    // Constructor: initializes the scheduler
    DiskScheduler(int start_pos, const std::vector<int>& requests)
        : initial_head_pos(start_pos), request_queue(requests) {}

    // 运行最短寻道时间优先 (SSTF) 算法
    // Run the Shortest Seek Time First (SSTF) algorithm
    void runSSTF() {
        std::cout << "\n--- Running SSTF Algorithm ---" << std::endl;
        if (request_queue.empty()) {
            std::cout << "Request queue is empty." << std::endl;
            return;
        }

        std::vector<int> sequence;
        int total_seek = 0;
        int current_pos = initial_head_pos;
        auto temp_queue = request_queue;

        sequence.push_back(current_pos);

        while (!temp_queue.empty()) {
            // 寻找距离当前磁头最近的磁道
            // Find the track closest to the current head position
            auto closest_it = std::min_element(temp_queue.begin(), temp_queue.end(),
                [current_pos](int a, int b) {
                    return std::abs(a - current_pos) < std::abs(b - current_pos);
                });
            
            int next_pos = *closest_it;
            total_seek += std::abs(next_pos - current_pos);
            current_pos = next_pos;
            
            sequence.push_back(current_pos);
            temp_queue.erase(closest_it);
        }

        printResults(sequence, total_seek);
    }

    // 运行电梯 (LOOK) 算法
    // Run the Elevator (LOOK) algorithm
    void runLOOK() {
        std::cout << "\n--- Running LOOK Algorithm ---" << std::endl;
        if (request_queue.empty()) {
            std::cout << "Request queue is empty." << std::endl;
            return;
        }

        std::vector<int> sequence;
        int total_seek = 0;
        int current_pos = initial_head_pos;
        auto temp_queue = request_queue;
        
        sequence.push_back(current_pos);

        // 将请求分为两部分：小于当前磁头的和大于等于当前磁头的
        // Partition requests into two groups: those less than the current head and those greater or equal
        std::vector<int> lower, upper;
        for (int track : temp_queue) {
            if (track < current_pos) {
                lower.push_back(track);
            } else {
                upper.push_back(track);
            }
        }

        // 排序以确定移动顺序
        // Sort to determine movement order
        std::sort(lower.begin(), lower.end(), std::greater<int>()); // 向下移动，从大到小
        std::sort(upper.begin(), upper.end());                      // 向上移动，从小到大

        // 假设磁头初始向上移动
        // Assume the head moves up initially
        for (int track : upper) {
            total_seek += std::abs(track - current_pos);
            current_pos = track;
            sequence.push_back(current_pos);
        }
        // 移动方向反转，处理另一部分请求
        // Reverse direction and service the other requests
        for (int track : lower) {
            total_seek += std::abs(track - current_pos);
            current_pos = track;
            sequence.push_back(current_pos);
        }

        printResults(sequence, total_seek);
    }

private:
    // 打印结果
    // Print the results
    void printResults(const std::vector<int>& sequence, int total_seek) {
        std::cout << "Track visit sequence: ";
        for (size_t i = 0; i < sequence.size(); ++i) {
            std::cout << sequence[i] << (i == sequence.size() - 1 ? "" : " -> ");
        }
        std::cout << std::endl;
        
        std::cout << "Total seek distance: " << total_seek << " tracks" << std::endl;
        if (request_queue.size() > 0) {
            double avg_seek = static_cast<double>(total_seek) / request_queue.size();
            std::cout << "Average seek length: " << std::fixed << std::setprecision(2) << avg_seek << " tracks" << std::endl;
        }
    }

    int initial_head_pos;
    std::vector<int> request_queue;
};

#endif // DISK_SCHEDULER_HPP
